package shake.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.servlet.ServletContext;

import com.google.inject.Inject;
import com.google.inject.Singleton;

@SuppressWarnings("unchecked")
@Singleton
public class ApplicationMap implements Map<String, Object> {
	@Inject
	ServletContext context;

	public void clear() {
		Enumeration<String> e = context.getAttributeNames();
		while (e.hasMoreElements()) {
			context.removeAttribute(e.nextElement());
		}
	}

	public boolean containsKey(Object key) {
		return context.getAttribute((String) key) != null;
	}

	public boolean containsValue(Object value) {
		Enumeration<String> e = context.getAttributeNames();
		while (e.hasMoreElements()) {
			Object v = context.getAttribute(e.nextElement());
			if (v.equals(value)) {
				return true;
			}
		}
		return false;
	}

	public Set<java.util.Map.Entry<String, Object>> entrySet() {
		HashSet<Entry<String, Object>> o = new HashSet<Entry<String, Object>>();
		Enumeration<String> e = context.getAttributeNames();
		while (e.hasMoreElements()) {
			final String key = e.nextElement();
			o.add(new Entry<String, Object>() {

				public String getKey() {
					return key;
				}

				public Object getValue() {
					return get(key);
				}

				public Object setValue(Object value) {
					return put(key, value);
				}
			});
		}

		return o;
	}

	public Object get(Object key) {
		return context.getAttribute((String) key);
	}

	public boolean isEmpty() {
		Enumeration e = context.getAttributeNames();
		return e.hasMoreElements() == false;
	}

	public Set<String> keySet() {
		Set<String> o = new HashSet<String>();
		Enumeration<String> e = context.getAttributeNames();
		while (e.hasMoreElements()) {
			o.add(e.nextElement());
		}
		return o;
	}

	public Object put(String key, Object value) {
		Object o = context.getAttribute(key);
		context.setAttribute(key, value);
		return o;
	}

	public void putAll(Map<? extends String, ? extends Object> m) {
		for (Entry<? extends String, ? extends Object> e : m.entrySet()) {
			put(e.getKey(), e.getValue());
		}
	}

	public Object remove(Object key) {
		Object o = context.getAttribute((String) key);
		context.removeAttribute((String) key);
		return o;
	}

	public int size() {
		int i = 0;
		Enumeration e = context.getAttributeNames();
		while (e.hasMoreElements()) {
			i++;
			e.nextElement();
		}
		return i;
	}

	public Collection<Object> values() {
		ArrayList<Object> o = new ArrayList<Object>();
		Enumeration<String> e = context.getAttributeNames();
		while (e.hasMoreElements()) {
			o.add(context.getAttribute(e.nextElement()));
		}
		return o;
	}

}
